﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using VisionCloud.Domain.Common;

namespace VisionCloud.Domain.Repository
{
    public interface IBaseRepository<T>
    {
        //查询相关
        IQueryable<T> GetAll();

        bool Any(Expression<Func<T, bool>> expression = null);

        Task<bool> AnyAsync(Expression<Func<T, bool>> expression = null);

        int Count(Expression<Func<T, bool>> expression = null);

        Task<int> CountAsync(Expression<Func<T, bool>> expression = null);

        T FirstOrDefault(Expression<Func<T, bool>> expression = null);

        Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> expression = null);

        T LastOrDefault(Expression<Func<T, bool>> expression = null);

        Task<T> LastOrDefaultAsync(Expression<Func<T, bool>> expression = null);

        T SingleOrDefault(Expression<Func<T, bool>> expression = null);

        Task<T> SingleOrDefaultAsync(Expression<Func<T, bool>> expression = null);

        T Single(Expression<Func<T, bool>> expression = null);

        Task<T> SingleAsync(Expression<Func<T, bool>> expression = null);

        T First(Expression<Func<T, bool>> expression = null);

        Task<T> FirstAsync(Expression<Func<T, bool>> expression = null);

        T Last(Expression<Func<T, bool>> expression = null);

        Task<T> LastAsync(Expression<Func<T, bool>> expression = null);

        List<T> Where(Expression<Func<T, bool>> expression);

        Task<List<T>> WhereAsync(Expression<Func<T, bool>> expression);

        List<T> WhereAsNoTracking(Expression<Func<T, bool>> expression);

        Task<List<T>> WhereAsNoTrackingAsync(Expression<Func<T, bool>> expression);

        T GetById(object id);

        Task<T> GetByIdAsync(object id);

        //操作相关

        /// <summary>
        /// 新增 特殊情况,含操作人信息的表自动插入操作人信息
        /// </summary>
        /// <param name="model"></param>
        /// <param name="autoSetOperatorInfo">自动写入操作人信息</param>
        void Add(T model, bool autoSetOperatorInfo = true);

        /// <summary>
        /// 新增 (先做唯一性判断)
        /// </summary>
        /// <param name="validModel"></param>
        /// <param name="model"></param>
        /// <param name="autoSetOperatorInfo"></param>
        /// <returns></returns>
        Task Add(AnyValidModel<T> validModel, T model, bool autoSetOperatorInfo = true);

        /// <summary>
        /// 新增 特殊情况,含操作人信息的表自动插入操作人信息
        /// </summary>
        /// <param name="models"></param>
        /// <param name="autoSetOperatorInfo">自动写入操作人信息</param>
        void AddRange(IEnumerable<T> models, bool autoSetOperatorInfo = true);

        /// <summary>
        /// 获取对象 ,如果不存在则插入一个新的
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="model"></param>
        /// <param name="autoSetOperatorInfo"></param>
        /// <returns></returns>
        Task<T> GetOrAdd(Expression<Func<T, bool>> expression, T model, bool autoSetOperatorInfo = true);

        /// <summary>
        /// 全字段更新 ,特殊情况,含操作人信息的更新时候有特殊逻辑
        /// </summary>
        /// <param name="model"></param>
        /// <param name="autoSetOperatorInfo">自动写入操作人信息</param>
        void Update(T model, bool autoSetOperatorInfo = true);

        /// <summary>
        /// 新增 (先做唯一性判断)
        /// </summary>
        /// <param name="validModel"></param>
        /// <param name="model"></param>
        /// <param name="autoSetOperatorInfo"></param>
        /// <returns></returns>
        Task Update(AnyValidModel<T> validModel, T model, bool autoSetOperatorInfo = true);

        /// <summary>
        /// 指定字段更新
        /// </summary>
        /// <param name="model"></param>
        /// <param name="handleField"></param>
        /// <param name="inUse"></param>
        void Update(T model, Expression<Func<T, object>> handleField, bool inUse = true);

        /// <summary>
        /// 删除 ,特殊情况,含操作人信息的表会进行伪删除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="realDelete">伪删除会自动设置操作的修改信息</param>
        void RemoveById(object id, bool realDelete = false);

        /// <summary>
        ///  删除 ,特殊情况,含操作人信息的表会进行伪删除
        /// </summary>
        /// <param name="model"></param>
        /// <param name="realDelete">伪删除会自动设置操作的修改信息</param>
        void Remove(T model, bool realDelete = false);

        /// <summary>
        ///  删除 ,特殊情况,含操作人信息的表会进行伪删除
        /// </summary>
        /// <param name="validModel"></param>
        /// <param name="model"></param>
        /// <param name="realDelete"></param>
        Task Remove(AnyValidModel<T> validModel, T model, bool realDelete = false);

        /// <summary>
        /// 批量删除 ,特殊情况,含操作人信息的表会进行伪删除
        /// </summary>
        /// <param name="list"></param>
        /// <param name="realDelete">伪删除会自动设置操作的修改信息</param>
        void RemoveRange(List<T> list, bool realDelete = false);

        void UpdateToDeleted(T model);

        //void Update(T entity, List<string> updatePropertyList = null, bool modified = true);

        /// <summary>
        /// 删除 特殊情况,含操作人信息的表自动插入操作人信息
        /// </summary>
        /// <param name="models"></param>
        void UpdateToDeleteRange(IEnumerable<T> models);

        #region 2019-10-11 刘冠冠

        T Update(Expression<Func<T, bool>> equalityExprssionForId, Action<T> updateAction);

        T Update<TPrimaryKey>(TPrimaryKey key, string keyColumnName, Action<T> updateAction);

        Task DeleteAsync(Expression<Func<T, bool>> predicate);

        Task DeleteAsync(T entity);

        //T Update(T entity, List<string> unModifyPropertyNames = null);

        #endregion 2019-10-11 刘冠冠
    }
}